

# Command to convert source video to uncompressed, video-only, Y4M format
cmd_src_to_y4m = "avconv -i {SRCVID!s} -s {RESOLUTION!s} -r 24 -f yuv4mpegpipe -pix_fmt yuv420p {Y4MVID!s}"

# Command to extract FLAC audio track from source video
cmd_src_to_flac = "avconv -i {SRCVID!s} {FLAC0!s}"

# Command to convert uncompressed video to VP8 video
cmd_y4m_to_vp8 = "vpxenc {Y4MVID!s} -o {VP8VID!s} --i420 -w 1920 -h 1080 -p 2 -t 3 --best --target-bitrate={BITRATE!s} --end-usage=vbr --auto-alt-ref=1 --fps={FRAMERATE!s}/{FRAMEDIV!s} -v --minsection-pct=5 --maxsection-pct=800 --lag-in-frames=16 --kf-min-dist=0 --kf-max-dist=480 --token-parts=3 --static-thresh=0 --drop-frame=0 --min-q=0 --max-q=6"


def src_to_y4m(source):
    """
    Convert source video (in format recognized by avconv) to Y4M video, using avconv.
    """
    subprocess.call(
      cmd_src_to_y4m.format(dict(video_conversion_parameters, SRCVID=source, Y4MVID='temp.y4m')),
      shell=True)

# Command to convert VP8 video back into lossless Y4M video for quality checking
cmd_vp8_to_y4m_chk = "avconv -i {VP8VID!s} -frames 30000 -f yuv4mpegpipe {VP8_Y4M_CHKVID!s}"



def convert_to_lrm(source, target, audio=None, subtitles=None, resolution=1080):
    """
    Given a source video file, create a Lib-Ray MKV feature media file
    at target path.
    
    Optionally, additional audio and subtitle tracks can be provided.
    """
    # Extract Y4M video from source video
    subprocess.call(['avconv', '-i', source, 
      '-s', 'hd1080', 
      '-r', '30', 
      '-f', 'yuv4mpegpipe',
      '-pix_fmt', 'yuv420p',
      'temp.y4m'])
      
    # Extract FLAC audio from source video (note: this assumes there is exactly one audio track)
    subprocess.call(['avconv', '-i', source, 'temp.flac'])
    
    # Encode the video to VP8/MKV
    subprocess.call(['vpxenc', 'temp.y4m', '-o', 'temp_vp8.mkv',
      '--i420', '-w', '1920', '-h', '1080', '-p', '2',
      '-t', '3', '--best', 
      '--target-bitrate=18000', '--end-usage=vbr', '--auto-alt-ref=1',
      '--fps=30', '-v', '--minsection-pct=5', '--maxsection-pct=800',
      '--lag-in-frames=16', '--kf-min-dist=0', '--kf-max-dist=480',
      '--token-parts=3', '--static-thresh=0', '--drop-frame=0',
      '--min-q=0', '--max-q=6'])

USAGE="""\
USAGE:

$ lrwiz

or

$ lrwiz [options] <input_video> [<audio>] [<assa>] [<output>]

This program creates an MKV/VP8/FLAC video program file compliant
with Lib-Ray standards and computes quality metrics information.

If run without arguments, lrwiz will ask you a series of questions
to configure itself, and then run the conversion. This is probably 
the simplest method unless you want to use a script to control it.

If output is omitted, one based on the input filename will be generated.
Several files will be created based on the output name, by default:

<output>.mkv --> the MKV/VP8/FLAC compressed video
<output>.ssim --> file with SSIM measurements
<output>.psnr --> file with PSNR measurements
<output>.log --> log report, with conversion detail

NOTE:
    You will need MANY GIGABYTES of disk space to run this program
    on a typical feature-length video, because it generates intermediate
    Y4M files both to master the video and to check the final video for
    quality compliance.
    
    You will also typically need to leave the job to run for HOURS,
    because the libvp8 compression software is quite slow and so is
    the psnr utility used to measure PSNR and SSIM quality metrics.
    
    When run interactively, the program will spawn a background process
    to do the actual conversion.

OPTIONS:

-h,--help      
    Print this help information and exit.

-f,--format=any     
    Specify the input video format. Currently only "png"
    is needed. In this case, the source is assumed to be
    a directory containing sequentially-numbered PNG files.
    Otherwise, any format recognized by avconv is acceptable
    as an input file.
                
-r,--resolution=hd1080
    Specify the output resolution to use. By default, this is
    hd1080 (meaning 1920x1080), but "sd", "hd720", and "4k" are
    recognized.
    
-R, --rate=30
    Force frame rate. Normally, the frame rate is kept, as Lib-Ray
    players are expected to be able to play files with any frame
    rate. For PNG streams, the framerate is assumed to be 30fps
    (exact), unless this option is used. Other frame rates may 
    be specified as needed.
    
-k, --keep-intermediates
    If specified, the program will keep all of the intermediate files
    it generates for you to inspect afterwards, including:
        .y4m --> Y4M lossless video from original video
        .y4r --> Recovered Y4M from VP8 (for quality metrics check)
        .vp8 --> MKV file with only the VP8-encoded video
        .###.flac --> FLAC files by sequence number
        .###.ogg  --> Ogg Vorbis files by sequence number
        .###.assa --> Subtitle files by sequence number
        
-A, --no-mux-audio
    If specified, any audio already muxed with the video source will be
    thrown away and the first explicit audio track will be the first
    track in the muxed video. Otherwise, the originally muxed-audio
    track will be the first and additional tracks will be added after
    it.
        
-a, --audio-main-tracks=<N>
    If given, the first <N> tracks provided will be converted to FLAC
    and treated as "main" soundtracks. Any additional tracks will be
    converted to Ogg Vorbis and considered auxilliary tracks.
    
-M, --no-metrics
    If specified, skip the generation of quality metrics information.
    This avoids a lot of time-consuming calculations.
    
-q, --query-job=<job_id>
    Does not run the program. Checks the log of the specified job (or
    all jobs if none specified) and reports current progress or problems.
"""


class default_options(object):
    # Options set from command line
    source = ""
    target = ""
    override_framerate = False
    source_mux_audio = True
    framerate = 30
    sourcetype = None
    pngstream = False
    keep_intermediates = False
    compute_metrics = True
    resolution = 'hd1080'
    
    
    
def wizard_interactive():
    """
    Run the wizard interactively on the command line, asking the
    user for necessary information.
    """
    op = default_options()
        
    print "Please answer the following. If you make a mistake, don't worry"
    print "you'll be asked to confirm or make corrections afterwards."
    while not confirmed:
      op.pngstream = yn_in(
          raw_input("Is the source a directory with frame images? [%s]" %
                yn_def(op.pngstream), op.pngstream)
      if op.pngstream:
        op.source = raw_input("Enter the directory with the images [%s]: " % 
                      op.source)
        if not op.target:
            op.target = op.source
        op.framerate = float(raw_input(
              "You must enter a frame rate for image streams [%f]: " % 
                      op.framerate))
      else:
        op.source = raw_input("Input video filename: [%s] " % 
                      op.source)
        if not op.target:
            op.target = op.source[:-4]
        op.override_framerate = yn_in(
          raw_input("Do you wish to force the frame rate to be adjusted? [%s]: " %
              yn_def(op.override_framerate)), op.override_framerate)
        if op.override_framerate:
            op.rate = float(raw_input("New frame rate: "))
      op.target = raw_input("Output filestem [%s]: " % op.target)
      print "Available Resolutions:"
      for name, (h, v) in standard_resolutions.items():
          print "\t%s\t%dx%d" % (name, h, v)
      check = False
      while not check:
          op.resolution = raw_input("Resolution [%s]: " % op.resolution)
          if op.resolution in standard_resolutions.keys():
              check = True
      op.compute_metrics = yn_in(
          raw_input("Compute quality metrics? [%s] " %
                yn_def(op.compute_metrics)), op.compute_metrics)
      op.keep_intermediates = yn_in(
          raw_input("Keep intermediate files? [%s] " %
                yn_def(op.keep_intermediates)), op.keep_intermediates)
      op.source_mux_audio = yn_in(
          raw_input("Use audio from video source file as first audio track? [%s] " %
                yn_def(op.source_mux_audio)), op.source_mux_audio)
      
     
  
  
def wizard_help():
    """
    Print help information.
    """
    print USAGE
 
def wizard_query():
    """
    Querty running lrwiz jobs and report status.
    """
    pass
  
def wizard


if __name__=='__main__':
    try:
      (options, files) = getopt.getopt(sys.argv[1:], "hf:r:R:Aa:kMO:q:", 
                             [  "help", "format=", "resolution=", "rate=", "no-mux-audio", 
                                "audio-main-tracks=", "keep-intermediates", "no-metrics",
                                "optimize-metrics=", "query-job="])    
      if not options and not files:
        wizard_interactive()
    except getopt.GetoptError as err:
        # print help information and exit:
        print str(err)
        wizard_help()
        sys.exit(2)
    for o, a in opts:
      if o in ("-h", "--help"):
        wizard_help()
        sys.exit(0)
      elif o in ("-A", "--no-mux-audio"):
        global_options.mux_audio = False
      elif o in ("-M", "--no-metrics"):
        global_options.compute_metrics = False
      elif o in ("-O", "--optimize"):
        global_options.optimize = True
        global_options.optimization_level = int(a)
      elif o in ("-k", "--keep-intermediates"):
        global_options.keep_intermediates = True
      elif o in ("-r", "--resolution"):
        if a in ("sd", "hd720", "hd1080", "4k"):
            global_options.resolution = a
        else:
            print "Unsupported resolution: %s" % a
            sys.exit(2)
      elif o in ("-a", "--audio-main-tracks"):
        global_options.audio_main_tracks = int(a)
      elif o in ("-R", "--rate"):
        global_options.frame_rate = float(a)
      elif o in ("-f", "--format"):
        if a in ("png","jpg"):
          global_options.image_stream = True
        elif a in ("mp4", "mpg", "webm", "y4m", "mov"):
          print "If you have problems with the input video, see the 'avconv' documentation."
          print "Be sure you are using the best available master video!"
          print "Any artifacts in the master video will be faithfully copied!"
      else:
        print "Unknown/unimplemented option: %s" % o
        print "Really, this shouldn't happen!"
        wizard_help()
        sys.exit(2)
      wizard_cli()
      
